const sleep = require('./sleep') 
const {redisCli} = require('../redis')

const redisLock = {
    newLock(lockName) {
        return new Lock(lockName) 
    },
}

function Lock(name) {
    this.name = name 
    this.millis = new Date().getTime()  
    this.unlockScript = `
        local millis = redis.call('get', KEYS[1]) 
        if millis==ARGV[1] then 
            redis.call('del', KEYS[1])
            return 1 
        else 
            return 0
        end
    `,
    this.unlockScriptArgLen = 1,
    this.lockScript = `
        return redis.call('set', KEYS[1], ARGV[1], 'EX', 180, 'NX') 
    `,
    this.lockScriptArgLen = 1 
}
// 初始化，缓存lua脚本到redis服务器  
Lock.prototype.init = function() {
    return new Promise((resolve, reject) => {
        redisCli.script('load', this.unlockScript, (err, sha) => {
            if(!err) {
                this.unlockSha = sha 
                redisCli.script('load', this.lockScript, (err2, sha2) => {
                    if(!err2) {
                        this.lockSha = sha2 
                        resolve(this) 
                    } else {
                        reject(err2) 
                    }
                }) 
            } else {
                reject(err) 
            }
        }) 
    })
}
// 加锁 
Lock.prototype.lock = async function() {
    let expire = 1000 * 60 * 3 
    let n = 10 
    while(n--) {
        // let ex = await redisCli.set(this.name, millis, 'NX', 'EX', 180) 
        // let ex = redisCli.setnx(this.name, millis) 
        // let promise = new Promise((resolve, reject) => {
        //     redisCli.setnx(this.name, millis, (err, result) => {
        //         console.log('err:', err)
        //         console.log('result:', result)
        //         resolve(result)
        //     }) 
        // })
        // let ex = await promise  
        let promise = new Promise((resolve, reject) => {
            redisCli.evalsha(this.lockSha, this.lockScriptArgLen, this.name, this.millis, (err, result) => {
                if(err) {
                    reject(err)
                }else{
                    resolve(result)
                }
            })
        })
        let ex = await promise  
        console.log('ex:', ex)
        //console.log('result:', result)
        // 其他锁存在
        if(!ex) {  
            await sleep(3)
            console.log('!ex')
            continue 
        } else {
            // 其他锁不存在，并已创建自己的锁  
            return true 
        }
    }
    return false 
}

// 解锁 
Lock.prototype.unlock = async function() {
    let unlock = await redisCli.evalsha(this.unlockSha, this.unlockScriptArgLen, this.name, this.millis)
    unlock = parseInt(unlock) 
    console.log('释放锁...')
    return !!unlock  
}


module.exports = Lock 

